Styling {ggplot2} graphics for accessibility

Nicola Rennie

My R Journey (so far…)

My R Journey (so far…)

A stream graph showing the use of R for the author between 2014 and present day. An increase is seen from 2019, and then more significantly in the last year.

My {ggplot2} journey (so far…)

A radar chart showing personality traits of Villanelle from Killing Eve. A radar chart showing personality traits of Eve from Killing Eve. A radar chart showing personality traits of Carolyn from Killing Eve.

My {ggplot2} journey (so far…)

A bar chart showing the number of books by the top 10 authors on the New York bestsellers list, where the bars are constructed of book titles stacked on top of each other.

My {ggplot2} journey (so far…)

A chart showing the amount of caffeine in different starbucks drinks. Caffeine amount is shown by colour of coffee cup icons.

My {ggplot2} journey (so far…)

A flowchart showing the story of goldilocks. A drawing of the bears and goldilocks has been added to the top-right corner.

What I do at Jumping Rivers?

Consultancy Hex stickers for four R packages - dplyr, ggplot2, tibble, and readr.

Training Cartoon of a teacher at the front of a class with a board showing an R.

R Community Shiny in Production conference logo of a robot holding a spanner.

Styling {ggplot2} graphics for accessibility


  Fonts


  Colours


  Alt Text

  Fonts

Fonts in {ggplot2}

  • {extrafont}
  • {ragg}
  • {showtext}

Fonts in {ggplot2}


Choose a font: fonts.google.com


Screenshot of Bungee Shade font on Google Fonts with the sample text reading Whereas recognition of the inherent dignity.

Fonts in {ggplot2}


Choose a font: fonts.google.com


Load it into R:

library(showtext)
font_add_google(name = "Bungee Shade", 
                family = "bungee")
showtext_auto()

Fonts in {ggplot2}

ggplot(data = mtcars,
       mapping = aes(x = mpg,
                     y = disp)) +
  geom_point() +
  labs(title = "My plot title")

A scatter plot of the mtcars data set from ggplot2 showing mpg on the x axis and disp on the y axis. The title of the plot is reads My Plot Title.

Fonts in {ggplot2}

ggplot(data = mtcars,
       mapping = aes(x = mpg,
                     y = disp)) +
  geom_point() +
  labs(title = "My plot title") +
  theme(
    plot.title = element_text(
      family = "bungee"))

A scatter plot of the mtcars data set from ggplot2 showing mpg on the x axis and disp on the y axis. The title of the plot is reads My Plot Title and is now shown in a different font.

How do I choose a font?

Screenshot of Google Fonts search page with top three font samples shown.

How do I choose a font?

Arial: Does it pass the 1Il test?


Times New Roman: Does it pass the 1Il test?


Courier New: Does it pass the 1Il test?

  Colours

Colour elements in {ggplot2}

Colour of geoms (mapped to variables in aes())

Example of a bar chart showing A, B, and C on the x axis and 1, 2, and 3 on the y axis. Bars are coloured based on the x axis values.

Colour of geoms (not mapped in aes())

Example of a bar chart showing A, B, and C on the x axis and 1, 2, and 3 on the y axis. Bars are all coloured blue.

theme() elements e.g. background colour

Example of a bar chart showing A, B, and C on the x axis and 1, 2, and 3 on the y axis. Background is coloured blue.

Defining colours in {ggplot2}

Let’s make an example plot to demonstrate…

name n
Crowned lemur 2094
Ring-tailed lemur 7490
Gray mouse lemur 12275

A group of eight ring-tailed lemurs huddled together on a wooden structure and looking at the camera. Image: Unsplash

Defining colours in {ggplot2}

ggplot(data = lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col()

Bar chart showing the number of lemurs for three different species.

Choosing colours in {ggplot2}

scale_*_brewer(): colorbrewer2.org

ggplot(data = lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_brewer(
    palette = "Dark2")

Bar chart showing the number of lemurs for three different species with colorbrewer Dark2 palette colours for the bars.

Choosing colours in {ggplot2}

Colour palette packages: github.com/EmilHvitfeldt/paletteer

library(rcartocolor)
ggplot(data = lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_carto_d("Prism")

Bar chart showing the number of lemurs for three different species with colours from the Prism palette from rcartocolor.

Choosing colours in {ggplot2}

Defining your own colours

Choosing colours in {ggplot2}

ggplot(data = lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_manual(
    values = c("#157145",
               "#4C1E4F",
               "#DE6E4B"))

Bar chart showing the number of lemurs for three different species with colours chosen manually.

Are your colours accessible?

my_colours = c("#157145", "#4C1E4F", "#DE6E4B")
  • {colorblindcheck}

  • {colorblindr}

{colorblindcheck}

colorblindcheck::palette_check(my_colours)
          name n tolerance ncp ndcp  min_dist mean_dist max_dist
1       normal 3  44.33725   3    3 44.337246  48.67622 55.30187
2 deuteranopia 3  44.33725   3    1 25.872723  34.57704 50.79886
3   protanopia 3  44.33725   3    1  9.345734  31.53395 46.54013
4   tritanopia 3  44.33725   3    2 41.560179  50.49023 60.86996

{colorblindr}

g <- ggplot(data = lemurs, 
            aes(x = name,
                y = n,
                fill = name)) +
  geom_col() +
  scale_fill_manual(
    values = c("#157145",
               "#4C1E4F",
               "#DE6E4B"))

Check it with {colorblindr}:

library(colorblindr)
cvd_grid(g)

{colorblindr}

Grid showing how the previous bar chart looks with different types of colorblindness

  Alt Text

How to write alt text for plots

Screenshot of article explaining how to write alt text for graphs, stating it should contain the chart type, type of data, what the chart shows, and a link to the dataset. Link: medium.com/nightingale/writing-alt-text-for-data-visualization-2a218ef43f81

Writing alt text in {ggplot2}

g <- ggplot(data = mtcars,
            mapping = aes(x = mpg,
                          y = disp)) +
  geom_point() +
  labs(alt = "Some of my own alt text.")


Extract the alt text:

get_alt_text(g)
[1] "Some of my own alt text."

Alt text in Quarto

```{r}
#| fig.alt: !expr ggplot2::get_alt_text(g)
#| fig-align: center
#| output-location: slide
g
```


The RMarkdown syntax:

{r, fig.alt=ggplot2::get_alt_text(g)}

Alt text in Quarto

Some of my own alt text.

Something a bit experimental…

remotes::install_github("nrennie/ggalttext")
library(ggalttext)

Automatically generating alt text

g1 <- ggplot(data = mtcars,
            mapping = aes(x = mpg,
                          y = disp)) +
  geom_point()
generate_alt_text(g1)
[1] "A plot with mpg on the x-axis and disp on the y-axis. The data is displayed using points."

Automatically generating alt text

g2 <- ggplot(data = mtcars,
            mapping = aes(x = mpg,
                          y = disp)) +
  geom_point() +
  labs(title = "My plot", 
       subtitle = "A descriptive subtitle.", 
       alt = "Some of my own alt text.")
generate_alt_text(g2)
[1] "My plot. A descriptive subtitle. A plot with mpg on the x-axis and disp on the y-axis. The data is displayed using points. Some of my own alt text."

Automatically generating alt text

```{r}
#| fig.alt: !expr ggalttext::generate_alt_text(g2)
#| fig-align: center
#| output-location: slide
g2
```

Automatically generating alt text

My plot. A descriptive subtitle. A plot with mpg on the x-axis and disp on the y-axis. The data is displayed using points. Some of my own alt text.

Automatically generating alt text

Screenshot of tweet from Hadley Wickham stating better alt text for ggplot2 is being explored.

Resources

{ggplot2}

Accessibility

Questions?